Skip to content

feat(spec): port formatCnpj to the bridge - #582

Closed
hyanmandian wants to merge 1 commit into
claude/bridge-is-valid-cnpjfrom
claude/bridge-format-cnpj
Closed

hyanmandian wants to merge 1 commit into
claude/bridge-is-valid-cnpjfrom
claude/bridge-format-cnpj

Conversation

@hyanmandian

Copy link
Copy Markdown
Member

What does this PR do?

Stacked on #581, which is stacked on #580 (the compiler). This PR's diff is only what formatCnpj adds.

The second utility, and the one that shows what sharing costs — which is the question a one-file-per-utility layout has to answer.

The diff, in full

file what it is
source/format-cnpj.ts the utility — 64 lines, one exported function
source/_internals/mask.ts laying a value over a mask, for every format* utility after this one
conformance/cases/format-cnpj.ts the arguments to replay — 29 lines

It reads the same two character classes isValidCnpj reads, out of the same source/_internals/cnpj.ts, and adds nothing to the compiler.

What each target ends up with

One self-contained module. The generated format-cnpj carries the mask helper and the two classes it uses, and not a line of the check digit code, because the compiler prunes what the utility cannot reach:

out/typescript/_bridge/format-cnpj.ts     105 lines   layout, class2, class4
out/typescript/_bridge/is-valid-cnpj.ts   142 lines   checkDigit, hasValidChecksum, isRepeated, 2 patterns

That is the property the npm package needs, and it is why the helpers are inlined rather than emitted as a shared module per target.

Parity

Three options that interact — pad, version, obfuscate — so all seven combinations are replayed against every input in the CNPJ corpus.

bash spec/bridge/conformance/run-all.sh:

target matched not expressible
typescript 4025 / 4025
python 4025 / 4025
ruby 4025 / 4025
go 3983 / 3983 42
rust 3983 / 3983 42
java 3983 / 3983 42
csharp 3983 / 3983 42
c abi 3983 / 3983 42

The forty-two are six numeric inputs × seven option sets: formatCnpj accepts string | number in JavaScript, and the compiled targets declare a string.

bash spec/bridge/conformance/verify-typescript.sh, now covering both CNPJ utilities:

Test Files  2 passed (2)
     Tests  57 passed | 3 todo (60)

Checklist

  • My commit/PR title follows Conventional Commits.
  • I added or updated tests covering this change (npm test) — not applicable: no change to src/. The generated output is checked against the package's existing suite by verify-typescript.sh, and against a recording of the shipped package by run-all.sh.
  • I updated the documentation if this adds/changes a utility — not applicable, no published utility added or changed.
  • npm run check passes locally (format, lint, types).
  • I ran npm run build:llms if I touched docs/utilities.md — not applicable, docs/ untouched.
  • This change does not introduce a breaking change.
  • This change does not add any runtime dependency.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UX1gTGeMTyoXQyr1qUoQKd


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 760790e6-c2db-4bec-81b3-90cb9e623600

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
brazilian-utils Error Error Sep 21, 2026 4:18am UTC

@codecov

codecov Bot commented Sep 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (claude/bridge-is-valid-cnpj@f701ac0). Learn more about missing BASE report.

Additional details and impacted files
@@                       Coverage Diff                       @@
##             claude/bridge-is-valid-cnpj      #582   +/-   ##
===============================================================
  Coverage                               ?   100.00%           
===============================================================
  Files                                  ?       183           
  Lines                                  ?      2069           
  Branches                               ?       612           
===============================================================
  Hits                                   ?      2069           
  Misses                                 ?         0           
  Partials                               ?         0           
Flag Coverage Δ
node 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

Tree-shaking report

No bundle size impact. All 155 exports are the same size as on the base branch (full import 648.9 KB, gzip 166.2 KB).

All exports (155)
Export Base Head Δ gzip
GetAddressInfoByCepError 966 B 966 B 0 B 600 B
GetAddressInfoByCepNotFoundError 1.0 KB 1.0 KB 0 B 618 B
GetAddressInfoByCepServiceError 1.0 KB 1.0 KB 0 B 617 B
GetAddressInfoByCepValidationError 1.0 KB 1.0 KB 0 B 620 B
GetCepInfoByAddressError 966 B 966 B 0 B 600 B
GetCepInfoByAddressNotFoundError 1.0 KB 1.0 KB 0 B 618 B
GetCepInfoByAddressValidationError 1.0 KB 1.0 KB 0 B 620 B
addBusinessDays 6.8 KB 6.8 KB 0 B 2.8 KB
capitalize 2.5 KB 2.5 KB 0 B 1.3 KB
convertCurrencyToWords 2.8 KB 2.8 KB 0 B 1.5 KB
convertDateToWords 3.2 KB 3.2 KB 0 B 1.7 KB
convertLicensePlateToMercosul 1.3 KB 1.3 KB 0 B 807 B
convertNumberToWords 2.4 KB 2.4 KB 0 B 1.3 KB
differenceInBusinessDays 6.9 KB 6.9 KB 0 B 2.9 KB
formatBoleto 1.4 KB 1.4 KB 0 B 837 B
formatCEP 1.2 KB 1.2 KB 0 B 778 B
formatCNPJ 1.4 KB 1.4 KB 0 B 854 B
formatCPF 1.3 KB 1.3 KB 0 B 806 B
formatCaepf 1.3 KB 1.3 KB 0 B 787 B
formatCei 1.3 KB 1.3 KB 0 B 785 B
formatCep 1.2 KB 1.2 KB 0 B 778 B
formatCertidao 1.3 KB 1.3 KB 0 B 789 B
formatCnae 1.2 KB 1.2 KB 0 B 782 B
formatCnh 1.3 KB 1.3 KB 0 B 780 B
formatCno 1.3 KB 1.3 KB 0 B 786 B
formatCnpj 1.4 KB 1.4 KB 0 B 854 B
formatCns 1.3 KB 1.3 KB 0 B 780 B
formatCpf 1.3 KB 1.3 KB 0 B 806 B
formatCurrency 1.8 KB 1.8 KB 0 B 1.0 KB
formatIban 1.1 KB 1.1 KB 0 B 696 B
formatLegalNature 1.2 KB 1.2 KB 0 B 777 B
formatLicensePlate 1.2 KB 1.2 KB 0 B 738 B
formatNcm 1.2 KB 1.2 KB 0 B 780 B
formatNfeKey 1.3 KB 1.3 KB 0 B 784 B
formatPassport 1.0 KB 1.0 KB 0 B 643 B
formatPhone 2.8 KB 2.8 KB 0 B 1.5 KB
formatPis 1.3 KB 1.3 KB 0 B 781 B
formatProcessoJuridico 1.3 KB 1.3 KB 0 B 785 B
formatVoterId 1.3 KB 1.3 KB 0 B 821 B
generateBoleto 2.0 KB 2.0 KB 0 B 1.1 KB
generateCNPJ 1.6 KB 1.6 KB 0 B 965 B
generateCPF 1.4 KB 1.4 KB 0 B 878 B
generateCep 984 B 984 B 0 B 610 B
generateCnh 1.4 KB 1.4 KB 0 B 828 B
generateCnpj 1.6 KB 1.6 KB 0 B 965 B
generateCpf 1.4 KB 1.4 KB 0 B 878 B
generateLegalNature 5.9 KB 5.9 KB 0 B 2.1 KB
generateLicensePlate 1.1 KB 1.1 KB 0 B 692 B
generatePassport 1.1 KB 1.1 KB 0 B 656 B
generatePhone 1.5 KB 1.5 KB 0 B 900 B
generatePis 1.2 KB 1.2 KB 0 B 744 B
generatePixPayload 6.3 KB 6.3 KB 0 B 2.8 KB
generateProcessoJuridico 1.4 KB 1.4 KB 0 B 870 B
generateRenavam 1.2 KB 1.2 KB 0 B 760 B
generateVoterId 1.7 KB 1.7 KB 0 B 1021 B
getAddressInfoByCep 4.1 KB 4.1 KB 0 B 1.9 KB
getAreaCodeInfo 3.9 KB 3.9 KB 0 B 1.4 KB
getAreaCodesByState 1.6 KB 1.6 KB 0 B 917 B
getBankByCode 38.6 KB 38.6 KB 0 B 9.8 KB
getBankByIspb 38.6 KB 38.6 KB 0 B 9.8 KB
getBanks 38.4 KB 38.4 KB 0 B 9.6 KB
getBoletoInfo 3.1 KB 3.1 KB 0 B 1.6 KB
getCbo 119.1 KB 119.1 KB 0 B 30.7 KB
getCepInfoByAddress 2.7 KB 2.7 KB 0 B 1.4 KB
getCertidaoInfo 1.8 KB 1.8 KB 0 B 1.0 KB
getCfop 68.9 KB 68.9 KB 0 B 6.9 KB
getCities 154.3 KB 154.3 KB 0 B 49.9 KB
getCnae 93.9 KB 93.9 KB 0 B 21.2 KB
getFormatLicensePlate 1.1 KB 1.1 KB 0 B 692 B
getHolidays 6.1 KB 6.1 KB 0 B 2.6 KB
getIbanInfo 1.6 KB 1.6 KB 0 B 955 B
getLegalNature 6.3 KB 6.3 KB 0 B 2.3 KB
getLegalNatures 5.9 KB 5.9 KB 0 B 2.1 KB
getLegalNaturesByCategory 6.5 KB 6.5 KB 0 B 2.4 KB
getMunicipalities 156.4 KB 156.4 KB 0 B 50.3 KB
getMunicipality 154.9 KB 154.9 KB 0 B 50.3 KB
getMunicipalityByCode 156.5 KB 156.5 KB 0 B 50.4 KB
getNfeKeyInfo 2.7 KB 2.7 KB 0 B 1.5 KB
getPixKeyInfo 4.5 KB 4.5 KB 0 B 2.0 KB
getPixPayloadInfo 2.9 KB 2.9 KB 0 B 1.4 KB
getStateByIbgeCode 3.2 KB 3.2 KB 0 B 1.1 KB
getStateCodeByName 3.2 KB 3.2 KB 0 B 1.1 KB
getStateNameByCode 3.1 KB 3.1 KB 0 B 1.0 KB
getStates 3.0 KB 3.0 KB 0 B 1017 B
getTimezoneByState 1.6 KB 1.6 KB 0 B 809 B
isBusinessDay 6.5 KB 6.5 KB 0 B 2.7 KB
isHoliday 6.4 KB 6.4 KB 0 B 2.7 KB
isValidBankAccount 7.4 KB 7.4 KB 0 B 2.8 KB
isValidBoleto 2.4 KB 2.4 KB 0 B 1.3 KB
isValidCEP 984 B 984 B 0 B 610 B
isValidCNPJ 1.6 KB 1.6 KB 0 B 914 B
isValidCPF 1.3 KB 1.3 KB 0 B 805 B
isValidCaepf 1.5 KB 1.5 KB 0 B 913 B
isValidCbo 119.2 KB 119.2 KB 0 B 30.7 KB
isValidCei 1.5 KB 1.5 KB 0 B 899 B
isValidCep 984 B 984 B 0 B 610 B
isValidCertidao 1.6 KB 1.6 KB 0 B 938 B
isValidCfop 68.9 KB 68.9 KB 0 B 6.9 KB
isValidCnae 94.0 KB 94.0 KB 0 B 21.2 KB
isValidCnh 1.4 KB 1.4 KB 0 B 856 B
isValidCno 1.5 KB 1.5 KB 0 B 901 B
isValidCnpj 1.6 KB 1.6 KB 0 B 914 B
isValidCns 1.5 KB 1.5 KB 0 B 925 B
isValidCpf 1.3 KB 1.3 KB 0 B 805 B
isValidCreditCard 1.4 KB 1.4 KB 0 B 868 B
isValidCsosn 1.2 KB 1.2 KB 0 B 737 B
isValidCst 1.8 KB 1.8 KB 0 B 1.0 KB
isValidEmail 1.0 KB 1.0 KB 0 B 622 B
isValidIE 5.7 KB 5.7 KB 0 B 2.1 KB
isValidIban 1.3 KB 1.3 KB 0 B 836 B
isValidIe 5.7 KB 5.7 KB 0 B 2.1 KB
isValidLandlinePhone 1.5 KB 1.5 KB 0 B 933 B
isValidLegalNature 5.8 KB 5.8 KB 0 B 2.1 KB
isValidLicensePlate 1.1 KB 1.1 KB 0 B 702 B
isValidMobilePhone 1.6 KB 1.6 KB 0 B 971 B
isValidNcm 114.2 KB 114.2 KB 0 B 24.6 KB
isValidNfeKey 2.7 KB 2.7 KB 0 B 1.5 KB
isValidPIS 1.2 KB 1.2 KB 0 B 785 B
isValidPassport 1.0 KB 1.0 KB 0 B 654 B
isValidPhone 2.6 KB 2.6 KB 0 B 1.3 KB
isValidPis 1.2 KB 1.2 KB 0 B 785 B
isValidPixKey 4.6 KB 4.6 KB 0 B 2.1 KB
isValidPixPayload 2.9 KB 2.9 KB 0 B 1.5 KB
isValidProcessoJuridico 1.3 KB 1.3 KB 0 B 787 B
isValidRegistroProfissional 1.6 KB 1.6 KB 0 B 964 B
isValidRenavam 1.3 KB 1.3 KB 0 B 815 B
isValidServicePhone 1.5 KB 1.5 KB 0 B 846 B
isValidVin 1.6 KB 1.6 KB 0 B 995 B
isValidVoterId 1.6 KB 1.6 KB 0 B 900 B
parseBoleto 1020 B 1020 B 0 B 634 B
parseCaepf 1003 B 1003 B 0 B 621 B
parseCbo 1002 B 1002 B 0 B 620 B
parseCei 1003 B 1003 B 0 B 619 B
parseCep 1002 B 1002 B 0 B 620 B
parseCertidao 1003 B 1003 B 0 B 621 B
parseCfop 1002 B 1002 B 0 B 620 B
parseCnae 1002 B 1002 B 0 B 620 B
parseCnh 1003 B 1003 B 0 B 621 B
parseCno 1003 B 1003 B 0 B 619 B
parseCnpj 1.1 KB 1.1 KB 0 B 669 B
parseCns 1003 B 1003 B 0 B 621 B
parseCpf 1003 B 1003 B 0 B 621 B
parseCurrency 1.4 KB 1.4 KB 0 B 881 B
parseIban 1.0 KB 1.0 KB 0 B 638 B
parseLegalNature 1002 B 1002 B 0 B 620 B
parseLicensePlate 1.0 KB 1.0 KB 0 B 638 B
parseNcm 1002 B 1002 B 0 B 620 B
parseNfeKey 1.0 KB 1.0 KB 0 B 659 B
parsePassport 1.0 KB 1.0 KB 0 B 637 B
parsePhone 1.1 KB 1.1 KB 0 B 707 B
parsePis 1003 B 1003 B 0 B 621 B
parseProcessoJuridico 1003 B 1003 B 0 B 621 B
parseVoterId 1.0 KB 1.0 KB 0 B 650 B
removeAccents 953 B 953 B 0 B 593 B
subBusinessDays 6.9 KB 6.9 KB 0 B 2.9 KB
How this is measured

Every export is imported alone into an esbuild consumer bundle (minified, tree-shaken) built from the head and from the base of this pull request; the sizes are the resulting bundles, gzip is their gzipped size. 🔴 marks a regression: a pre-existing export that grew more than 20% and more than 256 B, or the bundle importing every pre-existing export growing more than 5%. 🟡 is growth under the threshold, 🟢 a decrease, ⚪ no change, 🆕 an export that does not exist on the base (never a regression), 🗑️ an export that was removed. An intentional increase is accepted with the tree-shaking: accepted label.

The second utility, and the one that shows what sharing costs. It reads the same two
character classes `isValidCnpj` reads, out of the same `source/_internals/cnpj.ts`, and adds
a mask helper of its own under `source/_internals/mask.ts` — written once, for every
`format*` utility that comes after it.

What each target ends up with is still one self-contained module: the generated
`format-cnpj` carries the mask helper and the two classes it uses, and not a line of the
check digit code, because the compiler prunes what the utility cannot reach. That is the
property the npm package needs, and it is why the helpers are inlined rather than emitted as
a shared module per target.

Three options that interact — `pad`, `version`, `obfuscate` — over the same corpus, so all
seven combinations are replayed against every input.

    typescript  4025/4025      python  4025/4025      ruby  4025/4025
    go          3983/3983      rust    3983/3983      java  3983/3983
    csharp      3983/3983      cabi    3983/3983

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UX1gTGeMTyoXQyr1qUoQKd

Copy link
Copy Markdown
Member Author

Two red-looking things here, neither of them this PR's:

Everything on GitHub Actions is green or still running.


Generated by Claude Code

This branch had an error being deployed

1 failed deployment
Preview dbff7d85 Deployed Sep 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants